part of '../repository.dart';

const _kLearningInfoLearningSessionKey = 'learning_sessions';
const _kLearningInfoCurrentLearningIntervalStartTimeKey = 'current_learning_interval_start_time';
const _kLearningInfoCurrentLearningIntervalLastKnownActivityTimeKey =
    'current_learning_interval_last_known_activity_time';

class _LearningInfoDto extends Equatable {
  const _LearningInfoDto({
    required this.learningSessionDtos,
    required this.currentLearningIntervalStartTimeDto,
    required this.currentLearningIntervalLastKnownActivityTimeDto,
  });

  final BuiltList<_LearningSessionDto> learningSessionDtos;
  final _TimeDto? currentLearningIntervalStartTimeDto;
  final _TimeDto? currentLearningIntervalLastKnownActivityTimeDto;

  @override
  List<Object?> get props {
    return [
      learningSessionDtos,
      currentLearningIntervalStartTimeDto,
      currentLearningIntervalLastKnownActivityTimeDto,
    ];
  }

  factory _LearningInfoDto.fromJson(Map<String, dynamic> json) {
    // learning sessions

    final learningSessionMaps = List.castFrom<dynamic, Map>(json[_kLearningInfoLearningSessionKey]);

    final learningSessionDtos = learningSessionMaps.map((learningSessionMap) {
      final learningSessionJson =
          Map.castFrom<dynamic, dynamic, String, dynamic>(learningSessionMap);

      return _LearningSessionDto.fromJson(learningSessionJson);
    }).toBuiltList();

    // current learning interval start time

    _TimeDto? currentLearningIntervalStartTimeDto;

    final currentLearningIntervalStartTimeMap =
        json[_kLearningInfoCurrentLearningIntervalStartTimeKey] as Map?;

    if (currentLearningIntervalStartTimeMap != null) {
      final currentLearningIntervalStartTimeJson =
          Map.castFrom<dynamic, dynamic, String, dynamic>(currentLearningIntervalStartTimeMap);

      currentLearningIntervalStartTimeDto = _TimeDto.fromJson(currentLearningIntervalStartTimeJson);
    }

    // current learning interval last known activity time

    _TimeDto? currentLearningIntervalLastKnownActivityTimeDto;

    final currentLearningIntervalLastKnownActivityTimeMap =
        json[_kLearningInfoCurrentLearningIntervalLastKnownActivityTimeKey] as Map?;

    if (currentLearningIntervalLastKnownActivityTimeMap != null) {
      final currentLearningIntervalLastKnownActivityTimeJson =
          Map.castFrom<dynamic, dynamic, String, dynamic>(
              currentLearningIntervalLastKnownActivityTimeMap);

      currentLearningIntervalLastKnownActivityTimeDto =
          _TimeDto.fromJson(currentLearningIntervalLastKnownActivityTimeJson);
    }

    //

    return _LearningInfoDto(
      learningSessionDtos: learningSessionDtos,
      currentLearningIntervalStartTimeDto: currentLearningIntervalStartTimeDto,
      currentLearningIntervalLastKnownActivityTimeDto:
          currentLearningIntervalLastKnownActivityTimeDto,
    );
  }

  factory _LearningInfoDto.fromEntity(LearningInfo learningInfo) {
    // learning sessions

    final learningSessionDtos = learningInfo.learningSessions.map((learningSession) {
      return _LearningSessionDto.fromEntity(learningSession);
    }).toBuiltList();

    // current learning interval start time

    _TimeDto? currentLearningIntervalStartTimeDto;

    final currentLearningIntervalStartTime = learningInfo.currentLearningIntervalStartTime;

    if (currentLearningIntervalStartTime != null) {
      currentLearningIntervalStartTimeDto = _TimeDto.fromEntity(currentLearningIntervalStartTime);
    }

    // current learning interval last known activity time

    _TimeDto? currentLearningIntervalLastKnownActivityTimeDto;

    final currentLearningIntervalLastKnownActivityTime =
        learningInfo.currentLearningIntervalLastKnownActivityTime;

    if (currentLearningIntervalLastKnownActivityTime != null) {
      currentLearningIntervalLastKnownActivityTimeDto =
          _TimeDto.fromEntity(currentLearningIntervalLastKnownActivityTime);
    }

    //

    return _LearningInfoDto(
      learningSessionDtos: learningSessionDtos,
      currentLearningIntervalStartTimeDto: currentLearningIntervalStartTimeDto,
      currentLearningIntervalLastKnownActivityTimeDto:
          currentLearningIntervalLastKnownActivityTimeDto,
    );
  }

  Map<String, dynamic> toJson() {
    final learningSessionJsons = learningSessionDtos.map((learningSessionDto) {
      return learningSessionDto.toJson();
    }).toList();

    return {
      _kLearningInfoLearningSessionKey: learningSessionJsons,
      _kLearningInfoCurrentLearningIntervalStartTimeKey:
          currentLearningIntervalStartTimeDto?.toJson(),
      _kLearningInfoCurrentLearningIntervalLastKnownActivityTimeKey:
          currentLearningIntervalLastKnownActivityTimeDto?.toJson(),
    };
  }

  LearningInfo toEntity() {
    final learningSessions = learningSessionDtos.map((learningSessionDto) {
      return learningSessionDto.toEntity();
    }).toBuiltList();

    final currentLearningIntervalStartTime = currentLearningIntervalStartTimeDto?.toEntity();

    final currentLearningIntervalLastKnownActivityTime =
        currentLearningIntervalLastKnownActivityTimeDto?.toEntity();

    return LearningInfo(
      learningSessions: learningSessions,
      currentLearningIntervalStartTime: currentLearningIntervalStartTime,
      currentLearningIntervalLastKnownActivityTime: currentLearningIntervalLastKnownActivityTime,
    );
  }
}
